package com.atguigu.gmall.user.controller;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.gmall.common.constant.RedisConst;
import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.common.util.IpUtil;
import com.atguigu.gmall.model.user.UserInfo;
import com.atguigu.gmall.user.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author atguigu-mqx
 */
@RestController
@RequestMapping("/api/user/passport")
public class PassportApiController {

    @Autowired
    private UserService userService;

    @Autowired
    private RedisTemplate redisTemplate;

    //  /api/user/passport/login
    @PostMapping("login")
    public Result login(@RequestBody UserInfo userInfo, HttpServletRequest request){
        //  编写登录的业务逻辑。
        //  调用服务层方法
        UserInfo info = userService.login(userInfo);

        //  判断 数据库中用户信息
        if(info!=null){
            //  重点是如果有用户信息，我们要做什么处理?
            /*
                第一个 data = Result
                第二个 data = 相当于你要往 .ok(data);  可以将其看做一个对象 class 或者是 map！
                token = 相当于data的属性 || map 的key
              1.    auth.setToken(response.data.data.token) 需要将token 存储到 cookie 中！
              2.    auth.setUserInfo(JSON.stringify(response.data.data))  data存储的什么?
                    在cookie 中存储一个 userInfo 的 key , 用这个key 做什么?
                        当用户登录成功之后，需要在页面展示登录的昵称！ 用来获取用户昵称！

              3.    如何判断用户是否登录?
                        如果通过用户昵称判断不一定正确！ 因为昵称 存在cookie 中。cookie 中的数据可以操作的！
                        我们需要将用户的Id 存储到redis 中！

             */
            //  什么一个token 变量
            String token = UUID.randomUUID().toString();
            //  什么map 集合 来存储token
            HashMap<String, Object> map = new HashMap<>();
            map.put("token",token);
            map.put("nickName",info.getNickName());

            //  存储用户信息{userId}到缓存
            //  定义用户信息的key token 是在cookie 中的，随时可以获取到。注意不能使用userId
            //  key = user:login:token
            String userKey = RedisConst.USER_LOGIN_KEY_PREFIX + token;
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("userId",info.getId().toString());
             /*
                安全问题?
                缓存的key 是 user:token 组成的? token 存在cookie 中的！ cookie 中的数据 是不安全的！
                张三 登录了系统 ：{cookie 中应该有 token了 } 买买买.....
                李四 偷偷的盗用了 张三的cookie 中的 token user:token 组成了张三在缓存中存储的key 以及对应的value！
                    盗用了张三的登录权限了！
                    防止盗用cookie 信息！
                        验证用户是否登录的时候，既要判断用户 Id 是否为空， 同时还要判断一下第一次登录的iP地址与 第二次登录的ip 地址是否一致！
             */
            jsonObject.put("ip", IpUtil.getIpAddress(request));

            this.redisTemplate.opsForValue().set(userKey,jsonObject.toJSONString(),RedisConst.USERKEY_TIMEOUT, TimeUnit.SECONDS);
            //  返回map
            return Result.ok(map);
        }else {
            return Result.fail().message("用户名或密码不匹配");
        }
    }

    //  http://api.gmall.com/api/user/passport/logout
    @GetMapping("logout")
    public Result logout(HttpServletRequest request){
        //  通过js 方式将cookie 中的数据 变为null
        //  此处：需要删除缓存中的用户信息记录！
        //  组成缓存的key  cookie 中获取到token
        //        String token = "";  // token 存在cookie 中！
        //        Cookie[] cookies = request.getCookies();
        //        for (Cookie cookie : cookies) {
        //            if (cookie.getName().equals("token")) {
        //                token=cookie.getValue();
        //            }
        //        }
        //  必须在请求头中存储到token！
        String token = request.getHeader("token");

        String userKey = RedisConst.USER_LOGIN_KEY_PREFIX+token;
        //  删除缓存数据
        redisTemplate.delete(userKey);
        return Result.ok();
    }

}
